﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PSE.Framework.Communication.Configuration.Adapters;
using PSE.Framework.Communication.Configuration.Adapters.XmlHttp;
using PSE.Framework.Communication.Adapters.XmlHttp;
using PSE.Framework.Communication.Configuration.Adapters.File.FlatFile;
using PSE.Framework.Communication.Adapters.File.FlatFile;
using PSE.Framework.Communication.Configuration.Adapters.File.ExcelFile;
using PSE.Framework.Communication.Adapters.File.XmlFile;
using PSE.Framework.Communication.Adapters.File.ExcelFile;

using PSE.Framework.Communication.Configuration.Adapters.Stm;
using PSE.Framework.Communication.Adapters.Stm;
using PSE.Framework.Communication.Configuration.File;
using PSE.Framework.Communication.Configuration.File.FlatFile;
using PSE.Framework.Communication.Configuration.File.ExcelFile;
using PSE.Framework.Communication.Configuration.File.XmlFile;
using PSE.Framework.Communication.Configuration.XmlHttp;
using PSE.Framework.Communication.Configuration.Stm;
using PSE.Framework.Communication.Configuration.Tgp;
using PSE.Framework.Communication.Adapters.Tgp;

namespace PSE.Framework.Communication.Adapters
{
    /// <summary>
    /// Factory de adapters
    /// </summary>
    public class AdapterFactory : IAdapterFactory
    {
        /// <summary>
        /// Captura o Type do adapter a partir da configuração
        /// </summary>
        /// <param name="config">Configuração do adapter</param>
        /// <returns>Type do adapter</returns>
        public IEnumerable<Type> GetAdapterTypes(AdapterConfiguration config)
        {
            if (config == null)
                throw new ArgumentNullException("config");

            IEnumerable<Type> type = new List<Type>();

            // Adapters de entrada
            // --------------------------------------------------------------------
            if (config is InputAdapterConfiguration)
            {
                // File
                // --------------------------------------------------------------------

                // Flat File
                // --------------------------------------------------------------------
                if (config is FlatFileInputConfiguration)
                {
                    type = new List<Type>() { typeof(AsyncFlatFileInputAdapter), typeof(SyncFlatFileInputAdapter) };
                }
                // Excel File
                // --------------------------------------------------------------------
                else if (config is ExcelFileInputConfiguration)
                {
                    type = new List<Type>() { typeof(AsyncExcelFileInputAdapter), typeof(SyncExcelFileInputAdapter) };
                }
                // Xml File
                // --------------------------------------------------------------------
                else if (config is XmlFileInputConfiguration)
                {
                    type = new List<Type>() { typeof(AsyncXmlFileInputAdapter), typeof(SyncXmlFileInputAdapter) };
                }

                // Xml Http
                // --------------------------------------------------------------------
                else if (config is XmlHttpInputConfiguration)
                {
                    type = new List<Type>() { typeof(XmlHttpInputAdapter) };
                }

                // STM
                // --------------------------------------------------------------------
                else if (config is StmInputConfiguration)
                {
                    type = new List<Type>() { typeof(StmInputAdapter) };
                }

                // TGP
                // --------------------------------------------------------------------
                else if (config is TgpInputConfiguration)
                {
                    type = new List<Type>() { typeof(TgpInputAdapter) };
                }

            }
            // Adapters de saída
            // --------------------------------------------------------------------
            else if (config is OutputAdapterConfiguration)
            {
                // File
                // --------------------------------------------------------------------

                // Flat File
                // --------------------------------------------------------------------
                if (config is FlatFileOutputConfiguration)
                {
                    type = new List<Type>() { typeof(FlatFileOutputAdapter) };
                }
                // Excel File
                // --------------------------------------------------------------------
                else if (config is ExcelFileOutputConfiguration)
                {
                    type = new List<Type>() { typeof(ExcelFileOutputAdapter) };
                }
                // Xml File
                // --------------------------------------------------------------------
                else if (config is XmlFileOutputConfiguration)
                {
                    type = new List<Type>() { typeof(XmlFileOutputAdapter) };
                }

                // Xml Http
                // --------------------------------------------------------------------
                else if (config is XmlHttpOutputConfiguration)
                {
                    type = new List<Type>() { typeof(XmlHttpOutputAdapter) };
                }

                // TGP
                // --------------------------------------------------------------------
                else if (config is TgpOutputConfiguration)
                {
                    type = new List<Type>() { typeof(TgpOutputAdapter) };
                }
            }

            return type;
        }

        ///// <summary>
        ///// Cria um adapter a partir da configuração
        ///// </summary>
        ///// <param name="config">Configuração do adapter</param>
        ///// <returns>Instância do adapter</returns>
        //public IAdapter CreateAdapter(AdapterConfiguration config)
        //{
        //    if (config == null)
        //        throw new ArgumentNullException("config");

        //    if (config is InputAdapterConfiguration)
        //    {
        //        return this.CreateInputAdapter((InputAdapterConfiguration)config);
        //    }
        //    else if (config is OutputAdapterConfiguration)
        //    {
        //        return this.CreateOutputAdapter((OutputAdapterConfiguration)config);
        //    }
        //    else
        //    {
        //        throw new ArgumentException("Invalid configuration type", "config");
        //    }
        //}

        ///// <summary>
        ///// Cria um adapter de entrada a partir da configuração
        ///// </summary>
        ///// <param name="config">Configuração do adapter</param>
        ///// <returns>Instância do adapter</returns>
        //public IBaseInputAdapter CreateInputAdapter(InputAdapterConfiguration config)
        //{ 
        //    if (config == null)
        //        throw new ArgumentNullException("config");

        //    Type type = this.GetAdapterType(config);

        //    if (type == null)
        //        throw new ArgumentException("Invalid configuration type", "config");

        //    return (IBaseInputAdapter)Activator.CreateInstance(type);
        //}

        ///// <summary>
        ///// Cria um adapter de saída a partir da configuração
        ///// </summary>
        ///// <param name="config">Configuração do adapter</param>
        ///// <returns>Instância do adapter</returns>
        //public IBaseOutputAdapter CreateOutputAdapter(OutputAdapterConfiguration config)
        //{ 
        //    if (config == null)
        //        throw new ArgumentNullException("config");

        //    Type type = this.GetAdapterType(config);

        //    if (type == null)
        //        throw new ArgumentException("Invalid configuration type", "config");

        //    return (IBaseOutputAdapter)Activator.CreateInstance(type);
        //}
    }
}
